/** 构造参数:
 * table:必须，jQuery对象，目标table容器
 * dataUrl:必须，源数据REST地址，返回须为JSON列表
 * deleteUrl:可选，“删除”方法的REST地址，不提供则方法不可用
 * changeUrl:可选，“修改”方法的REST地址，不提供则方法不可用
 * insertUrl:可选，“添加”方法的REST地址，不提供则方法不可用
 * dataDescriptions:可选，数据描述数组，每个元素对应一列，若不提供则“添加”和“修改”方法不可用。数组元素的属性包括：
 * 		column:数据库列名
 * 		header:表头字符串
 * 		value:JSON对象中的属性名或字符串常量
 * 		isDelete:是否为“删除”操作链接，属性不存在则默认为false
 * 		isHidden:是否为隐藏项，属性不存在则默认为false
 * 		isConstant:是否为常量，属性不存在则默认为false
 *  	editable:是否可修改，属性不存在则默认为true可修改
 *  page:可选，分页描述，参数属性包括：
 *  	container：可选，分页控件所在的DIV容器，不提供则默认在table容器的最下
 *  	itemsPerPage：可选，每页条目数量，默认为20
 *  	
 */
function DataGrid(args){
	self=this;
	this.table=args.table;
	this.dataUrl=args.dataUrl;
	this.deleteUrl=args.deleteUrl;
	this.changeUrl=args.changeUrl;
	this.insertUrl=args.insertUrl;
	this.dataDescriptions=args.dataDescriptions;
}
DataGrid.prototype = {
	/**
	 * 构造函数
	 */
	constructor: DataGrid,
	/** renderData方法参数：
	 * builder：可选，回调函数，输入一个JSON对象返回TR对象
	 * dataArgs：可选，源数据URL调用时的附加参数
	 * deleteArgs：可选，“删除”URL调用时的附加参数
	 * changeArgs：可选，“修改”URL调用时的附加参数
	 * insertArgs：可选，“添加”URL调用时的附加参数
	 */
	renderData: function(args){
		var opt = args ? args : {};
		$.ajax(this.dataUrl,{data:opt.dataArgs,async:false,success:function(result){
			if(opt.builder)
				$.each(result,function(i,n){
					self.table.append(builder.call(this,n));
				});
			else
				$.each(result,function(i,n){
					self.table.append(self._buildTr(n,opt));
				});
			if(self.insertUrl)
				self.table.append($("<tr></tr>").append($("<td><u>添加</u></td>").click(function(){
					self._add($(this).parent(), opt);
				})));
		}});
	},
	/** renderHeader方法参数：
	 * items数组：表头字符串数组
	 */
	renderHeader: function(items){
		var tr=$("<tr>");
		if(self.dataDescriptions)
			$.each(this.dataDescriptions,function(i,n){
				if(n.header)
					tr.append($("<th>").append(n.header));
			});
		else if(items)
			$.each(items,function(i,n){
				tr.append($("<th>").append(n));
			});
		else
			$.each(self.table.find("tr:first td"),function(i,n){
				tr.append($("<th>").append("第"+i+"列"));
			});
		this.table.find("tbody").before($("<thead>").append(tr));
	},
	_change: function(inputNode,opt){
		if(!inputNode.is(".input")){
			text=inputNode.text();
			inputNode.addClass("input").html("<input text='' value='"+inputNode.text()+"'>").find("input").focus().blur(function(){
				self._save($(this),text,confirm("确定要修改？"),opt);
			}).keyup(function(event){
				if((event || window.event).keyCode == 27)
					self._save($(this),text,false,opt);
				if((event || window.event).keyCode == 13){
					$(this).unbind("blur");
					self._save($(this),text,confirm("确定要修改？"),opt);
				}
			});
		}
	},
	_save: function(inputNode,origin,confirm,opt){
		var tdNode = inputNode.parent();
		tdNode.removeClass("input");
		if(!confirm){
			tdNode.html(origin);
		}else{
			var tr=inputNode.parent().parent();
			var id=tr.find("td:hidden").text();
			var i=tr.find("td").index(inputNode.parent());
			var types=$.map(self.dataDescriptions,function(n){return n.column;});
			$.post(self.changeUrl,jQuery.extend({id:id,type:types[i],text:inputNode.val()},opt.changeArgs),function(result){
				tdNode.html(result=="success"?inputNode.val():origin);
			});
		}
	},
	_delete: function(targetNode,id,opt){
		if(!confirm("确定删除？"))
			return;
		$.post(self.deleteUrl,jQuery.extend({id:id},opt.daleteArgs),function(result){
			if(result=="success")
				targetNode.remove();
		});
	},
	_add: function(targetNode, opt){
		if(!confirm("确定添加？"))
			return;
		$.post(self.insertUrl,opt.insertArgs,function(result){
			var tr=self._buildTr({id:result},opt);
			targetNode.before(tr);
		});
	},
	_buildTr: function(item,opt){
		var tr=$("<tr>");
		if(!this.dataDescriptions){
			$.each(item,function(i,n){
				tr.append($("<td>").append(n));
			});
		}else{
			$.each(self.dataDescriptions,function(i,n){
				var td=$("<td>").dblclick(function(){
					self._change($(this),opt);
				}).hover(function(){
					$(this).addClass("blue");
				},function(){
					$(this).removeClass("blue");
				});
				if(n.isDelete)
					td.append($("<u>"+n.value+"</u>")).click(function(){
						self._delete($(this).parent(),item.id,opt);
					});
				else if(n.isConstant)
					td.append(n.value);
				else
					td.append(item[n.value]);
				n.isHidden?td.hide():td.show();
				n.style?td.attr("style",n.style):true;
				tr.append(td);
			});
		}
		return tr;
	}
};